﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.Events;
using ModulesInfrastructure.ViewModels;
using ServerConnection.ShopServiceReference;
using System.Windows;
using System.Windows.Input;
using ServerConnection;
using System.ComponentModel;
using EventInfrastructure;


namespace ModuleOrder.ViewModels
{
    /// <summary>
    /// ViewModel of the orderList
    /// </summary>
    public class OrderViewModel : SharedViewModel, IOrderViewModel
    {
        #region Constructor

        /// <summary>
        /// The constructor of the OrderViewModel
        /// </summary>
        /// <param name="eventAggregator"></param>
        public OrderViewModel(IEventAggregator eventAggregator)
        {
            m_eventAggregator = eventAggregator;
            m_eventAggregator.GetEvent<GetOrderEditEvent>().Subscribe(onEditClick);
            m_eventAggregator.GetEvent<CancelOrderEvent>().Subscribe(onCancelOrderEvent);
            m_eventAggregator.GetEvent<PayedOrderEvent>().Subscribe(onPayedOrderEvent);
            m_eventAggregator.GetEvent<AssignOrderEvent>().Subscribe(onAssignOrderEvent);
            m_eventAggregator.GetEvent<GetOrderAddEvent>().Subscribe(onGetOrderAddEvent);
            m_eventAggregator.GetEvent<RefreshOrderListEvent>().Subscribe(onRefreshOrderListEvent);
            onRefreshOrderListEvent(true);          
        }

        #endregion constructor


        #region Public properties

        /// <summary>
        /// Returns the orders of this office
        /// </summary>
        public ObservableCollection<OrderView> LoadOrders
        {
            get
            {
                return m_orderList;
            }
        }


        /// <summary>
        /// The current selected order
        /// </summary>
        public OrderView OnSelectedOrder
        {
            get { return m_selectedOrder; }
            set
            {
                m_selectedOrder = value;
                if (m_selectedOrder != null)
                {
                    m_eventAggregator.GetEvent<OrderSelectedEvent>().Publish(m_selectedOrder.Id);
                }
            }

        }

        #endregion


        #region Private methods


        /// <summary>
        /// Gets the list of the orders
        /// </summary>
        /// <param name="flag">bool value</param>
        private void onRefreshOrderListEvent(bool flag)
        {
            OrderView[] array = ServerConnection.Service.Instance.GetOrderList(null, 1, 100);
            if (array != null)
            {
                m_orderList.Clear();

                foreach (OrderView arrayItem in array)
                {
                    m_orderList.Add(arrayItem);
                }
            }
        }


        /// <summary>
        /// Publishes the event on the edit button click 
        /// </summary>
        /// <param name="flag">bool value</param>
        private void onEditClick(bool flag)
        {
            if (m_selectedOrder != null)
            {
                if (m_selectedOrder.Status != OrderStatus.Closed)
                    m_eventAggregator.GetEvent<OrderEditEvent>().Publish(m_selectedOrder.Id);
            }
        }


        /// <summary>
        /// Publishes the event on the add button click 
        /// </summary>
        /// <param name="flag">bool value</param>
        private void onGetOrderAddEvent(bool flag)
        {
            m_eventAggregator.GetEvent<OrderAddEvent>().Publish(true);
        }


        /// <summary>
        /// Changes the status of the order to "Closed"
        /// </summary>
        /// <param name="flag">bool value</param>
        private void onPayedOrderEvent(bool flag)
        {
            if (OnSelectedOrder.Status != OrderStatus.Closed && OnSelectedOrder.Executor != null)
            {
                OrderFull currentOrder = ServerConnection.Service.Instance.CloseOrder(OnSelectedOrder.Id);
                OnSelectedOrder.Status = currentOrder.Status;
            }
        }


        /// <summary>
        /// Cancels the order and unreserved all products in it
        /// </summary>
        /// <param name="flag">bool value</param>
        private void onCancelOrderEvent(bool flag)
        {
            if (OnSelectedOrder!= null && OnSelectedOrder.Status != OrderStatus.Closed)
            {
                bool result = ServerConnection.Service.Instance.CancelOrder(OnSelectedOrder.Id);

                if (result.Equals(true))
                {
                    OnSelectedOrder.Status = OrderStatus.Canceled;
                }
            }
        }


        /// <summary>
        /// Assignes the order to the current executor and changes it's status
        /// </summary>
        /// <param name="flag">bool value</param>
        private void onAssignOrderEvent(bool flag)
        {
            if (OnSelectedOrder.Executor == null && OnSelectedOrder.Status != OrderStatus.Closed && OnSelectedOrder.Status != OrderStatus.Canceled)
            {
                OrderFull currentOrder = ServerConnection.Service.Instance.ReserveOrder(OnSelectedOrder.Id, ServerConnection.Service.CurrentUser.Id);
                OnSelectedOrder.Executor = currentOrder.Executor;
            }
        }

        #endregion


        #region Private members

        private ObservableCollection<OrderView> m_orderList = new ObservableCollection<OrderView>();

        /// <summary>
        /// The current selected order
        /// </summary>
        private OrderView m_selectedOrder;

        private IEventAggregator m_eventAggregator;

        #endregion
    }
}
